package com.kyh.util.qiniucloud;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.kyh.util.DateUtil;
import com.qiniu.cdn.CdnManager;
import com.qiniu.cdn.CdnResult;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;

public class QiniuCloudUtil {
	private static final Logger logger = Logger.getLogger(QiniuCloudUtil.class);
	
	private static QiniucloudProperties qiniucloudProperties = QiniucloudProperties.getInstance();
	public static String AccessKey = qiniucloudProperties.getAccessKey(); // AccessKey
	public static String SecretKey = qiniucloudProperties.getSecretKey(); // SecretKey
	public static String qiniuBucketName = qiniucloudProperties.getQiniuBucketName(); // 
	public static String qiniuDomainhttps = qiniucloudProperties.getQiniuDomainhttps(); // 含https的域名
	public static String qiniuDomain = qiniucloudProperties.getQiniuDomainAll(); // 含http的域名
	
	public final static String qiniuPrefix = "upload"; // 路径前缀

	public QiniuCloudUtil() {
		init();
	}

	private void init() {

	}

	/**
	 * 返回格式如：prefix/yyyy/MM/dd/hhmmssSSS.txt
	 * @param prefix 前缀，如：upload
	 * @param sourceFileName 原始文件名，如1.txt
	 */
	public String getPath(String prefix, String sourceFileName) {
		String path = DateUtil.getYear() + "/" + DateUtil.getMonth() + "/" + DateUtil.getDayofMonth() + "/"
				+ DateUtil.getHHmmssSSS(new Date());
		if (StringUtils.isNotBlank(prefix)) {
			path = prefix + "/" + path;
		}
		sourceFileName = sourceFileName.replace('\\', '/');
		sourceFileName = sourceFileName.substring(sourceFileName.lastIndexOf("/") + 1);
		int index = sourceFileName.lastIndexOf(".");
		String ext = null;
		if (index >= 0) {
			ext = StringUtils.trimToNull(sourceFileName.substring(index + 1));
		}
		return path + "." + (ext == null ? null : (ext));
	}

	/**
	 * 
	 * @param data 输入流的二进制数据
	 * @param path 文件路径，格式：upload/xxxx/xxxx.xxx
	 * @return 返回文件的全路径，如http://file.xxx.com/upload/xxxx/xxxx.xxx
	 * @throws Exception
	 */
	public String uploadToQiniu(byte[] data, String path) throws Exception {
		
		try {
			String token = Auth.create(AccessKey, SecretKey).uploadToken(qiniuBucketName);
			UploadManager uploadManager = new UploadManager(new Configuration(Region.region0()));
			Response res = uploadManager.put(data, path, token);
			if (!res.isOK()) {
				throw new RuntimeException("上传七牛出错：" + res.toString());
			}
		} catch (Exception e) {
			throw new Exception("上传文件失败，请核对七牛配置信息", e);
		}
		return qiniuDomain + "/" + path;
	}

	/**
	 * 上传 自动生成文件路径 在（upload/）下
	 */
	public String upload(InputStream inputStream, String filename) throws Exception {
		try {
			byte[] data = IOUtils.toByteArray(inputStream);
			return uploadToQiniu(data, getPath(qiniuPrefix, filename));
		} catch (IOException e) {
			throw new Exception("上传文件失败", e);
		}
	}

	/**
	 * 上传(指定文件名和路径)
	 */
	public String uploadByFilename(InputStream inputStream, String filename) throws Exception {
		try {
			byte[] data = IOUtils.toByteArray(inputStream);
			String token = Auth.create(AccessKey, SecretKey).uploadToken(qiniuBucketName);
			UploadManager uploadManager = new UploadManager(new Configuration(Zone.autoZone()));
			Response res = uploadManager.put(data, filename, token);
			if (!res.isOK()) {
				throw new RuntimeException("上传七牛出错：" + res.toString());
			}
		} catch (IOException e) {
			throw new Exception("上传文件失败", e);
		}
		return qiniuDomain + "/" + filename;
	}

	/**
	 * 删除
	 */
	public boolean del(String key) {
		boolean falg = false;
		try {
			Auth auth = Auth.create(AccessKey, SecretKey);
			BucketManager bucketManager = new BucketManager(auth, new Configuration(Zone.zone0()));
			bucketManager.delete(qiniuBucketName, key);
			falg = true;
			logger.info("删除文件成功");
		} catch (QiniuException e) {
			e.printStackTrace();
			falg = false;
			logger.error("删除文件失败");
		}
		return falg;
	}

	/**
	 * 复制
	 */
	public boolean copy(String sourceKey, String targetKey) throws Exception {
		boolean falg = false;
		try {
			Auth auth = Auth.create(AccessKey, SecretKey);
			BucketManager bucketManager = new BucketManager(auth, new Configuration(Zone.zone0()));
			bucketManager.copy(qiniuBucketName, sourceKey, qiniuBucketName, targetKey);
			falg = true;
			logger.info("文件复制成功");
		} catch (QiniuException e) {
			e.printStackTrace();
			falg = false;
			logger.error("文件复制失败");
		}
		return falg;
	}

	/**
	 * 刷新url缓存
	 */
	public boolean cdnRefreshUrls(String[] urls) {
		boolean falg = false;
		try {
			Auth auth = Auth.create(AccessKey, SecretKey);
			CdnManager cdnManager = new CdnManager(auth);
			CdnResult.RefreshResult result = cdnManager.refreshUrls(urls);
			if (result.code == 200) {
				falg = true;
				logger.info("刷新url缓存成功");
			}
		} catch (QiniuException e) {
			e.printStackTrace();
			falg = false;
			logger.error("刷新url缓存失败");
		}
		return falg;
	}

	/**
	 * 刷新文件夹下所有
	 */
	public boolean cdnRefreshDirs(String[] dirs) {
		boolean falg = false;
		try {
			Auth auth = Auth.create(AccessKey, SecretKey);
			CdnManager cdnManager = new CdnManager(auth);
			CdnResult.RefreshResult result = cdnManager.refreshDirs(dirs);
			if (result.code == 200) {
				falg = true;
				logger.info("刷新文件缓存成功");
			}
		} catch (QiniuException e) {
			e.printStackTrace();
			falg = false;
			logger.info("刷新文件缓存失败");
		}
		return falg;
	}

	/**
	 * 通过请求文件 判断文件是否存在
	 * @param key 文件名，如：upload/2020/01/01/aaa.jpg
	 */
	public boolean FilePathExists(String key) throws Exception {
		BufferedReader in = null;
		try {
			URL realUrl = new URL(qiniuDomain + "/" + key);
			URLConnection connection = realUrl.openConnection();
			connection.setRequestProperty("accept", "*/*");
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			connection.connect();
			in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
		} catch (Exception e) {
			return false;
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 使用MultipartFile上传是调用
	 */
	public String upload(byte[] data, String filename) throws Exception {
		return upload(data, getPath(qiniuPrefix, filename));
	}

	/**
	 * 下载
	 */
	public String download(String key, Long deadline) {
		Long aa = System.currentTimeMillis();
		System.out.println(aa);
		Auth auth = Auth.create(AccessKey, SecretKey);
		String url = qiniuDomain + "/" + key;
		String downloadUrl = "";
		if (deadline == null || deadline <= 0L) {
			downloadUrl = auth.privateDownloadUrl(url);
		} else {
			downloadUrl = auth.privateDownloadUrl(url, deadline);// 第二个参数 过期时间
																	// 单位：秒
		}
		Long bb = System.currentTimeMillis();
		System.out.println(aa-bb);
		return downloadUrl;
	}

	public String uploadToken() throws Exception {
		try {
			return Auth.create(AccessKey, SecretKey).uploadToken(qiniuBucketName);
		} catch (Exception e) {
			throw new Exception("获取上传token失败，请核对七牛配置信息", e);
		}
	}

	public static void main(String[] args) throws Exception {
//		Date dateNow = new Date();
//		File file = new File("D:/1.txt");
//		QiniuCloudUtil qiniuCloudUtil = new QiniuCloudUtil();
//		String filename = "/" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(dateNow)
//				+ "/" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + ".txt";
//		String url = qiniuCloudUtil.upload(new FileInputStream(file), filename);
//		System.out.println(url);
//		
		/*
		//构造一个带指定 Region 对象的配置类
		Configuration cfg = new Configuration(Region.region0());
		//...其他参数参考类注释
		UploadManager uploadManager = new UploadManager(cfg);
		//...生成上传凭证，然后准备上传
		String accessKey = "your access key";
		String secretKey = "your secret key";
		String bucket = "your bucket name";
		//如果是Windows情况下，格式是 D:\\qiniu\\test.png
		String localFilePath = "/home/qiniu/test.png";
		//默认不指定key的情况下，以文件内容的hash值作为文件名
		String key = null;
		Auth auth = Auth.create(accessKey, secretKey);
		String upToken = auth.uploadToken(bucket);
		try {
		    Response response = uploadManager.put(localFilePath, key, upToken);
		    //解析上传成功的结果
		    DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
		    System.out.println(putRet.key);
		    System.out.println(putRet.hash);
		} catch (QiniuException ex) {
		    Response r = ex.response;
		    System.err.println(r.toString());
		    try {
		        System.err.println(r.bodyString());
		    } catch (QiniuException ex2) {
		        //ignore
		    }
		}
		*/
	}
}
